package utils

import (
	"bufio"
	"io"
	"path/filepath"
	"strings"

	"gitee.com/u-language/u-language/ucom/enum"
)

// Ret_type_no_lea 返回类型的非取地址表示,以及包含几个取地址
//   - 对于 &T,返回T,1
//   - 对于 T,返回T,0
func Ret_type_no_lea(s string) (string, int) {
	i := 0
	for s[0] == '&' {
		s = s[1:]
		i++
	}
	return s, i
}

// Ret_no_lea 返回类型的非取地址表示
func Ret_no_lea(s string) string {
	for s[0] == '&' {
		s = s[1:]
	}
	return s
}

// NoExtBase 调用 [filepath.Base] 并去除扩展名
func NoExtBase(f string) string {
	tmp := filepath.Base(f)
	return strings.Split(tmp, ".")[0]
}

// ReadAllLine 读取全部并按行分割
func ReadAllLine(r *bufio.Reader) ([]string, error) {
	var Filestr = make([]string, 0, 8)
	for { //给代码按行分割
		s, end, err := ReadLine(r)
		if err != nil {
			return Filestr, err
		}
		if end {
			return Filestr, nil
		}
		Filestr = append(Filestr, s)
	}

}

func ReadLine(r *bufio.Reader) (string, bool, error) {
	line1, islong, err := r.ReadLine() //获取一行代码
	if err != nil {
		if err == io.EOF { //读完了
			return "", true, nil
		}
		return "", true, err
	}
	if !islong { //读取了一行
		return string(line1), false, nil
	} else {
		//如果islong==true，就是一次没有读取完一行
		var filebuf strings.Builder
		var err error
		_, err = filebuf.Write(line1)
		if err != nil {
			return "", true, err
		}
		for { //重复读取直到读取完一行
			line2, islong, err := r.ReadLine()
			if err != nil {
				if err == io.EOF { //读完了
					return "", true, nil
				}
				return "", true, err
			}
			if !islong { //读取了一行
				filebuf.Write(line2)
				return filebuf.String(), false, nil
			}
			//没有读取完一行
			_, err = filebuf.Write(line2)
			if err != nil {
				return "", true, err
			}
		}
	}
}

// element type 返回连续类型的元素类型与长度,以及是不是连续类型
func Elem(T string) (elem string, len string, yes bool) {
	if T[0] != '[' {
		return "", "", false
	}
	left, right := 0, 0
	for i, v := range T {
		switch v {
		case '[':
			left++
		case ']':
			right++
			if left == right {
				return T[i+1:], T[:i+1], true
			}
		}
	}
	return "", "", false
}

// Split_package_name 返回去除包名的字符串
func Split_package_name(s string) (string, string) {
	slice := strings.SplitN(s, enum.PackageSep, 2)
	if len(slice) > 1 {
		if slice[0] == "unsafe" { //如果是unsafe包
			return "", s
		}
		leaCount := 0
		for len(slice[0]) > 0 && slice[0][0] == '&' { //计算取地址数量
			leaCount++
			slice[0] = slice[0][1:]
		}
		if leaCount != 0 { //如果是指针类型
			return slice[0], strings.Repeat("&", leaCount) + slice[1]
		}
		return slice[0], slice[1]
	}
	return "", s
}
